package com.xuelang.pipeline.infrastructure.pipeline.repository;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xuelang.pipeline.client.common.result.PageRecord;
import com.xuelang.pipeline.client.pipeline.dto.PipelineTemplateQuery;
import com.xuelang.pipeline.domain.pipeline.PipelineTemplate;
import com.xuelang.pipeline.domain.pipeline.repository.PipelineTemplateRepository;
import com.xuelang.pipeline.infrastructure.pipeline.converter.PipelineTemplateToPipelineTemplateDOConverter;
import com.xuelang.pipeline.infrastructure.pipeline.dataobject.PipelineTemplateDO;
import com.xuelang.pipeline.infrastructure.pipeline.mapper.PipelineTemplateMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 流水线模板仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class PipelineTemplateRepositoryImpl implements PipelineTemplateRepository {

    @Autowired
    PipelineTemplateMapper pipelineTemplateMapper;

    @Override
    public PageRecord<PipelineTemplate> pageList(long currentPage, long pageSize, PipelineTemplateQuery pipelineTemplateQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<PipelineTemplate> page = new Page<>(currentPage, pageSize);
        MPJLambdaWrapper<PipelineTemplateDO> wrapper = new MPJLambdaWrapper<PipelineTemplateDO>();
        if (pipelineTemplateQuery != null) {
            wrapper.selectAll(PipelineTemplateDO.class)
                    .like(StrUtil.isNotBlank(pipelineTemplateQuery.getCondition()), PipelineTemplateDO::getName, pipelineTemplateQuery.getCondition())
                    .apply(StrUtil.isNotBlank(pipelineTemplateQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", pipelineTemplateQuery.getStartDate())
                    .apply(StrUtil.isNotBlank(pipelineTemplateQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", pipelineTemplateQuery.getEndDate())
                    .orderByDesc(PipelineTemplateDO::getCreateTime);
        }
        pipelineTemplateMapper.selectJoinPage(page, PipelineTemplate.class, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords());
    }

    @Override
    public List<PipelineTemplate> list(PipelineTemplateQuery pipelineTemplateQuery) {
        MPJLambdaWrapper<PipelineTemplateDO> wrapper = new MPJLambdaWrapper<PipelineTemplateDO>();
        if (pipelineTemplateQuery != null) {
            wrapper.selectAll(PipelineTemplateDO.class)
                    .like(StrUtil.isNotBlank(pipelineTemplateQuery.getCondition()), PipelineTemplateDO::getName, pipelineTemplateQuery.getCondition())
                    .apply(StrUtil.isNotBlank(pipelineTemplateQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", pipelineTemplateQuery.getStartDate())
                    .apply(StrUtil.isNotBlank(pipelineTemplateQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", pipelineTemplateQuery.getEndDate())
                    .orderByDesc(PipelineTemplateDO::getCreateTime);
        }
        return pipelineTemplateMapper.selectJoinList(PipelineTemplate.class, wrapper);
    }


    @Override
    public Boolean save(PipelineTemplate pipelineTemplate) {
        return pipelineTemplateMapper.insert(PipelineTemplateToPipelineTemplateDOConverter.INSTANCE.pipelineTemplateToPipelineTemplateDO(pipelineTemplate)) == 1;
    }

    @Override
    public Boolean update(PipelineTemplate pipelineTemplate) {
        return pipelineTemplateMapper.update(
                PipelineTemplateToPipelineTemplateDOConverter.INSTANCE.pipelineTemplateToPipelineTemplateDO(pipelineTemplate),
                Wrappers.lambdaQuery(PipelineTemplateDO.class).eq(PipelineTemplateDO::getUuid, pipelineTemplate.getUuid())) == 1;
    }

    @Override
    public Boolean delete(String pipelineTemplateUuid) {
        return pipelineTemplateMapper.delete(Wrappers.lambdaQuery(PipelineTemplateDO.class).eq(PipelineTemplateDO::getUuid, pipelineTemplateUuid)) == 1;
    }

    @Override
    public PipelineTemplate query(String pipelineTemplateUuid) {
        PipelineTemplateDO pipelineTemplateDO = pipelineTemplateMapper.selectOne(Wrappers.lambdaQuery(PipelineTemplateDO.class).eq(PipelineTemplateDO::getUuid, pipelineTemplateUuid));
        return PipelineTemplateToPipelineTemplateDOConverter.INSTANCE.pipelineTemplateDOToPipelineTemplate(pipelineTemplateDO);
    }

    @Override
    public List<PipelineTemplate> list(PipelineTemplate pipelineTemplate) {
        List<PipelineTemplateDO> pipelineTemplateDOS = pipelineTemplateMapper
                .selectList(Wrappers.lambdaQuery(PipelineTemplateDO.class)
                        .eq(PipelineTemplateDO::getComponentType, pipelineTemplate.getComponentType())
                        .eq(PipelineTemplateDO::getProgramLanguage, pipelineTemplate.getProgramLanguage())
                        .orderByDesc(PipelineTemplateDO::getCreateTime));
        return pipelineTemplateDOS.stream().map(PipelineTemplateToPipelineTemplateDOConverter.INSTANCE::pipelineTemplateDOToPipelineTemplate).collect(Collectors.toList());
    }

    @Override
    public Boolean existsName(String pipelineTemplateUuid, String pipelineTemplateName) {
        List<PipelineTemplateDO> pipelineTemplateDOS = pipelineTemplateMapper.selectList(Wrappers.lambdaQuery(PipelineTemplateDO.class).eq(PipelineTemplateDO::getName, pipelineTemplateName));
        if (ObjectUtil.isEmpty(pipelineTemplateDOS)) {
            return false;
        }
        return pipelineTemplateDOS.stream().anyMatch(pipelineTemplateDO -> !ObjectUtil.equals(pipelineTemplateUuid, pipelineTemplateDO.getUuid()));
    }
}
